#ifndef TextCmd_First
#define TextCmd_First
#ifdef __GNUG__
#pragma interface
#endif

#include "TextStyles.h"
#include "TextView.h"

class Text;
class StyledText;
class RunArray;

typedef void (*TextRangeFP)(Text *t, int at, int *s, int *e);

extern void CharacterRange(Text *t, int at, int *start, int *end);
extern void WordRange(Text *t, int at, int *start, int *end);
extern void ParagraphRange(Text *t, int at, int *start, int *end);

//---- TextRangeSelector -------------------------------------------------------

class TextRangeSelector: public Command {
public:
	TextRangeSelector(TextView*, TextRangeFP rf= CharacterRange);
	Command *TrackMouse(TrackPhase, Point, Point, Point);
	virtual void DoPress(SelPoint nextp, int start, int end);
	virtual void DoMove(SelPoint nextp, int start, int end);

protected:
	TextView *tv;
	SelPoint startp, endp;
	TextRangeFP range;
	void Range(Text *t, int at, int *from, int *to);
};

//---- ExtendTextRangeSelector -------------------------------------------------

class ExtendTextRangeSelector: public TextRangeSelector {
public:
	ExtendTextRangeSelector(TextView*, TextRangeFP rf= CharacterRange);
	void DoPress(SelPoint nextp, int start, int end);
	void DoMove(SelPoint nextp, int start, int end);

private:
	bool swap, first;
};

//---- QuickPasteSelector ------------------------------------------------------

class QuickPasteSelector: public TextRangeSelector {
public:
	QuickPasteSelector(TextView*, int, int);
	Command *TrackMouse(TrackPhase, Point, Point, Point);

private:
	int from, to;
};

//---- DragAndDropSelector -----------------------------------------------------

class DragAndDropSelector: public Command {
public:
	DragAndDropSelector(TextView*, int, int, bool paste);
	Command *TrackMouse(TrackPhase, Point, Point, Point);
	void TrackFeedback(Point, Point, bool);
private:
	int from, to, dst;
	TextView *tv;
	Text *t;
	bool moved, paste;
	Point delta;
	static GrCursor oldcursor;

	void DrawCaretFeedback(int at);
};

//---- TextCommand -------------------------------------------------------------

class TextCommand: public Command {
public:
	MetaDef(TextCommand);
	TextCommand(TextView*, int cmdNo, char *cmdName, bool saveOldtext= TRUE);
	~TextCommand();
	void RestoreSelection();
	void RedoIt();

protected:
	TextView *tv;
	Text *oldText;
	int oldStart, oldEnd;
};

//---- CutCopyTextCommand ------------------------------------------------------

class CutCopyTextCommand: public TextCommand {
public:
	MetaDef(CutCopyTextCommand);
	CutCopyTextCommand(TextView*, int cmdNo, char *cmdName= 0);
	void DoIt();
	void UndoIt();
};

//---- PasteTextCommand --------------------------------------------------------

class PasteTextCommand: public TextCommand {
public:
	MetaDef(PasteTextCommand);
	PasteTextCommand(TextView*, Text*, int cmdNo= cPASTE, char *cmdName= 0);
	~PasteTextCommand();
	void DoIt();
	void UndoIt();

protected:
	Text *pastetext;
	int newStart, newEnd;
	bool moved;
};

//---- MoveTextCommand ---------------------------------------------------------

class MoveTextCommand: public Command {
public:
	MoveTextCommand(TextView*, int from, int to, int dst);
	~MoveTextCommand();
	void DoIt();
	void UndoIt();

private:
	int from, to, dst;
	TextView *tv;
	Text *mt;
};

//---- TypingCommand -----------------------------------------------------------

class TypingCommand: public TextCommand {
public:
	MetaDef(TypingCommand);
	TypingCommand(TextView *t, int cmdNo, char *cmdName);
	~TypingCommand();
	void UndoIt();
	void RedoIt();
	void AddChar(int n= 1);
	void DelChar();

protected:
	Text *backspaceBuf;    // to store text backspaced over
	Text *newText;
	int newStart;
};

//---- CharStyleCommand --------------------------------------------------------

class CharStyleCommand: public TextCommand {
public:
	MetaDef(CharStyleCommand);
	CharStyleCommand(TextView *t, int cmdNo, char *cmdName, TxtCharProp mode,
												const CharStyleSpec &newStyle);
	~CharStyleCommand();
	void DoIt();
	void UndoIt();
	void RedoIt();

private:
	RunArray *newStyles, *oldStyles;
	TextView *tvp;
	StyledText *st;
	TxtCharProp mode;
	CharStyleSpec style;
};

//---- ParaStyleCommand --------------------------------------------------------

class ParaStyleCommand: public TextCommand {
public:
	MetaDef(ParaStyleCommand);
	ParaStyleCommand(TextView *t, int cmdNo, char *cmdName, TxtParaProp prop,
													const ParaDesc &newStyle);
	~ParaStyleCommand();
	void DoIt();
	void UndoIt();
	void RedoIt();

	TxtParaProp GetNewStyle(ParaDesc &newStyle);
	void Apply(TxtParaProp p, const ParaDesc &newStyle);
	void NotifyWhenDone(EvtHandler *evt);

private:
	RunArray *newStyles, *oldStyles;
	TextView *tvp;
	StyledText *st;
	TxtParaProp mode;
	ParaDesc style;
	EvtHandler *notify;

};

#endif
